package com.zhongying.jf.resolver;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.dubbo.remoting.RemotingException;
import com.alibaba.dubbo.rpc.RpcException;
import com.chinazyjr.framework.common.enums.ErrorCodeEnum;
import com.chinazyjr.framework.common.exceptions.BizException;
import com.zhongying.jf.exception.ZhongyingiException;
import com.zhongying.jf.result.ResultSupport;
import com.zhongying.jf.util.JacksonUtil;

/**
 * Created with IntelliJ IDEA. User: liuhao 全局异常信息处理类
 */
@Component
public class ExceptionHandlerResolver implements HandlerExceptionResolver, Ordered {

    private static final Logger LOG = LoggerFactory.getLogger(ExceptionHandlerResolver.class);

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o,
            Exception ex) {
        ResultSupport<?> result = new ResultSupport<>();
        if (ex instanceof RemotingException) {
            LOG.error("dubbo服务Remoting异常,具体错误为：" + ex.getMessage(), ex);
            result = new ResultSupport<>(ErrorCodeEnum.DUBBO_ERROR);
        } else if (ex instanceof RpcException) {
            LOG.error("dubbo服务Rpc异常,具体错误为：" + ex.getMessage(), ex);
            result = new ResultSupport<>(ErrorCodeEnum.DUBBO_ERROR);
        } else if (ex instanceof IOException) {
            LOG.error("请求资源找不到,具体错误为：" + ex.getMessage(), ex);
            result = new ResultSupport<>(ErrorCodeEnum.IO_ERROR);
        } else if (ex instanceof ZhongyingiException) {
            LOG.error("业务异常，具体错误为：" + ex.getMessage(), ex);
            result = new ResultSupport<>(((ZhongyingiException) ex).getCode(), ex.getMessage());
        } else if (ex instanceof BizException) {
            LOG.error("业务异常，具体错误为：" + ex.getMessage(), ex);
            result = new ResultSupport<>(((BizException) ex).getCode(), ex.getMessage());
        } else {
            LOG.error("系统异常，具体错误为：" + ex.getMessage(), ex);
            result = new ResultSupport<>(ErrorCodeEnum.SYSTEM_ERROR);
        }
        writeJsonResponse(result, response);
        /*
         * try { LOG.error("resolveException:{}",
         * ExceptionUtils.getStackTrace(ex)); writeJsonResponse(ex, response); }
         * catch (Exception e) {
         * LOG.error("Response JSON Write Output Error : {}", e); }
         */
        return new ModelAndView();// 返回null表示由下一个ExceptionResolver处理
    }

    private void writeJsonResponse(ResultSupport<?> result, HttpServletResponse response) {
        response.reset();
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");
        try {
            JacksonUtil.getMapper().writeValue(response.getOutputStream(), result);
        } catch (IOException e) {
            LOG.error("write error", e);
        }

    }

    /*
     * private void writeJsonResponse(Exception ex, HttpServletResponse
     * response) { response.setCharacterEncoding("utf-8");
     * response.setContentType("application/json;charset=utf-8"); try {
     * ZhongyingiException pex = (ZhongyingiException) ex;
     * JacksonUtil.getMapper().writeValue(response.getOutputStream(), new
     * ResultSupport(pex.getErrorCode(), pex.getMessage(),null));
     * LOG.error(pex.getMessage()+"-------------------"+pex.getErrorCode()); }
     * catch (Exception e) { String stack = getStackTraceString(ex);
     * ResultSupport responseModel = new ResultSupport();
     * responseModel.setCode("network_exception"); responseModel.setMsg("网络异常!"
     * ); LOG.error(stack); try {
     * JacksonUtil.getMapper().writeValue(response.getOutputStream(),
     * responseModel); } catch (IOException e1) { } } }
     * 
     * private String getStackTraceString(Exception e) { StringWriter sw = new
     * StringWriter(); PrintWriter pw = new PrintWriter(sw); try {
     * e.printStackTrace(pw); return sw.toString(); } finally { pw.close(); } }
     */

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
